from django.shortcuts import render,HttpResponse,redirect
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
import json,requests,time,re
from django.utils.safestring import mark_safe
from bs4 import BeautifulSoup
from django.views.decorators.cache import cache_page
# Create your views here.
"""
1.消息群发
2.清理僵尸好友
3.消息定时发送
4.语音转发
5.刷微信消息

"""
# f=open('hello.txt','r',encoding='utf-8').read()
TIP=0
MemberList=[]
# Public=json.loads(f)      #公众号
# Group=json.loads(f)       #微信群
CODE=""
head_jpg=''
COOKIES={}
CTIME=str(time.time())
DICT={}
USER_INFO={}
logoff=False


#微信扫码登陆页
def login(request):
    URL='https://login.wx.qq.com/jslogin?appid=wx782c26e4c19acffb&fun=new&lang=zh_CN&_=%s'%CTIME
    respone=requests.request(
        url=URL,
        method='get',
        headers={
            'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0',
            'Referer':'https://wx.qq.com/'
        }
    )
    global CODE
    CODE=respone.text.split('"')[1]
    return render(request,'login.html',{'code':CODE})

#登陆授权
def check_login(request):
    global DICT
    global head_jpg
    URL='https://login.wx2.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=%s&tip=%s&r=-2098658326&_=%s'%(CODE,TIP,CTIME)
    r1=requests.get(
        url=URL
    )
    res={'code':None}
    if '408' in r1.text:
        print('无人扫码')
        res['code']=408
    elif 'window.code=201' in r1.text:
        print('已经扫码，请手机上点击确认按钮！')
        res['code']=201
        imgpath=re.findall("window.userAvatar = '(.*)';",r1.text)
        #将用户头像下载到本地
        import base64,os
        from django.conf import settings
        head_img=imgpath[0].split(',')[1] #得到base64编码的微信头像
        head=base64.b64decode(head_img)
        head_name=CODE+'.jpg'
        head_jpg='/static/user_head/'+head_name
        local_path=os.path.join(settings.BASE_DIR,'static/user_head',head_name) #将头像解码后放到/static目录下供前端调用
        f=open(local_path,'wb')
        f.write(head)
        f.close()
        res['imgpath']=imgpath
    elif 'window.code=200' in r1.text:
        clean_userinfo()
        global logoff
        logoff=False
        print('已确认登陆，正在授权')
        res['code']=200
        redrict_url=re.findall('redirect_uri="(.*)"',r1.text)[0]
        redrict_url+='&fun=new&version=v2&lang=zh_CN'
        r2=requests.get(redrict_url)
        COOKIES.update(r2.cookies.get_dict())
        soup=BeautifulSoup(r2.text,features='lxml')
        for tag in soup.find('error').children:
            DICT[tag.name]=tag.string

    return HttpResponse(json.dumps(res))

def clean_userinfo():
    global MemberList
    global COOKIES
    try:
        COOKIES.clear()
        MemberList.clear()
    except Exception as e:
        pass
def logout(request):
    clean_userinfo()
    try:
        print('-----------------------','用户注销登陆')
        global logoff
        logoff=True

        post_dict={
            'sid':DICT['wxsid'],
            'uin':DICT['wxuin']
        }
        r=requests.post(
            url='https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=1&skey=%s'%DICT['skey'],
            json=post_dict,
            cookies=COOKIES
        )
        return redirect('/')
    except Exception as e:
        return redirect('/')

#更新好友列表
def update(request):
    global MemberList
    MemberList.clear()
    json_data={
            "BaseRequest":{
                           "Uin":DICT['wxuin'],
                           "Sid": DICT['wxsid'],
                           "Skey":DICT['skey']
                           },
            "DeviceID":"e301257987250377",
            "Sid":DICT['wxsid'],
            "Skey":DICT['skey'],
            "Uin":DICT['wxuin']
        }
    #获取用户个人信息
    url1='https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=-2015355380&lang=zh_CN&pass_ticket=%s'%DICT['pass_ticket']
    respone=requests.post(
        url=url1,
        json=json_data
    )
    respone.encoding='utf-8'
    userinfo=json.loads(respone.text)['User']
    USER_INFO['username']=userinfo['NickName']
    USER_INFO['id']=userinfo['UserName']
    USER_INFO['Signature']=userinfo['Signature']
    USER_INFO['sex']=userinfo['Sex']


    #获取所有联系人
    url='https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?lang=zh_CN&pass_ticket=%s&r=1543913826350&seq=0&skey=%s'%(DICT['pass_ticket'],DICT['skey'])
    r1=requests.post(
        url=url,
        json=json_data,
        cookies=COOKIES,
        headers={
            'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0',
            'Referer':'https://wx.qq.com/'
        }

    )
    r1.encoding = 'utf-8'
    USER_INFO_DICT=json.loads(r1.text) #获取的所有用户信息
    MemberList=[]  #用户列表
    for i in USER_INFO_DICT['MemberList']:
        if i['AttrStatus'] != 0:
            MemberList.append(i)
    return HttpResponse('ok')

# @cache_page(60 * 15) #启用前端缓存
#显示微信联系人列表
def user(request):
    global MemberList
    global USER_INFO
    if logoff is False:
        try:
            if len(MemberList) != 0: #如果已经在微信服务器获取过用户信息了就直接返回本地以获取的数据
                print('展示本地已有联系人列表')
                paginator=Paginator(MemberList,10)
                page = request.GET.get('page')
                try:
                    contacts = paginator.page(page)
                except PageNotAnInteger:
                    # 如果page不是一个整数，则展示第一页。
                    contacts = paginator.page(1)
                except EmptyPage:
                    # 如果page不在范围内（例如，9999），则展示结果的最后一页。
                    contacts = paginator.page(paginator.num_pages)

            else: #如果本地没有获取过用户好友信息就连接服务器获取
                json_data={
                    "BaseRequest":{
                                   "Uin":DICT['wxuin'],
                                   "Sid": DICT['wxsid'],
                                   "Skey":DICT['skey']
                                   },
                    "DeviceID":"e301257987250377",
                    "Sid":DICT['wxsid'],
                    "Skey":DICT['skey'],
                    "Uin":DICT['wxuin']
                }
                #获取用户个人信息
                url1='https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=-2015355380&lang=zh_CN&pass_ticket=%s'%DICT['pass_ticket']
                respone=requests.post(
                    url=url1,
                    json=json_data
                )
                respone.encoding='utf-8'
                userinfo=json.loads(respone.text)['User']
                USER_INFO['username']=userinfo['NickName']
                USER_INFO['id']=userinfo['UserName']
                USER_INFO['Signature']=userinfo['Signature']
                USER_INFO['sex']=userinfo['Sex']

                #获取所有联系人
                url='https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?lang=zh_CN&pass_ticket=%s&r=1543913826350&seq=0&skey=%s'%(DICT['pass_ticket'],DICT['skey'])
                r1=requests.post(
                    url=url,
                    json=json_data,
                    cookies=COOKIES,
                    headers={
                        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0',
                        'Referer':'https://wx.qq.com/'
                    }
                )
                r1.encoding = 'utf-8'
                USER_INFO_DICT=json.loads(r1.text) #获取的所有好友信息
                #生成公众号，微信群信息供其它视图调用
                print('开始生成联系人信息')
                for i in USER_INFO_DICT['MemberList']:
                    if i['AttrStatus'] != 0:
                        MemberList.append(i)
                paginator=Paginator(MemberList,10)
                page = request.GET.get('page')
                try:
                    contacts = paginator.page(page)
                except PageNotAnInteger:
                    # 如果page不是一个整数，则展示第一页。
                    contacts = paginator.page(1)
                except EmptyPage:
                    # 如果page不在范围内（例如，9999），则展示结果的最后一页。
                    contacts = paginator.page(paginator.num_pages)
            return render(request,'user.html',{
                    'user':contacts,                #分页后的好友信息
                    'MemberCount':len(MemberList), #联系人总数
                    'userinfo':USER_INFO,      #微信个人信息
                    'url_path':request.path,
                    'head_jpg':head_jpg
                                                   })

        except KeyError as e: #如果用户在其他设备上登陆或未登录会触发keyerror错误（字典中无用户信息）
            print('后端出现错误：',e)
            return render(request,'error.html')
    else:
        return redirect('/')
#搜索好友
def search(request):
    if request.method == 'POST':
        print('---------------搜索朋友')
        search_fields=[]
        name=request.POST.get('search')
        for i in MemberList:
            if name in i['NickName'] or name in i['RemarkName']:
                search_fields.append(i)
        return HttpResponse(json.dumps(search_fields,ensure_ascii= False))

#发送消息
def send_msg(request):
    ids=request.POST.get('users')

    ids=json.loads(ids)
    msg=request.POST.get('msg')
    count=int(request.POST.get('count'))
    if None in ids:
        ids.remove(None)

    status=True
    for user_id in ids:
        ctime=time.time()
        post_dict = {
            'BaseRequest': {
                'DeviceID': "e402310790089148",
                'Sid':DICT['wxsid'],
                'Uin':DICT['wxuin'],
                'Skey':DICT['skey'],
            },
            "Msg": {
                'ClientMsgId': ctime,
                'Content': msg,
                'FromUserName':USER_INFO['id'],
                'LocalID': ctime,
                'ToUserName': user_id,
                'Type': 1
            },
            'Scene':0
        }
        url="https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?lang=zh_CN&pass_ticket=%s"%DICT['pass_ticket']
        #群发消息，默认为一条
        if count == 1:
            r1=requests.post(
            url=url,
            data=bytes(json.dumps(post_dict,ensure_ascii=False),encoding='utf-8'),
            cookies=COOKIES
        )
        else:
            for i in range(count):
                ctime=time.time()
                post_dict['Msg']['LocalID']=ctime
                post_dict['Msg']['ClientMsgId']=ctime
                r1=requests.post(
                url=url,
                data=bytes(json.dumps(post_dict,ensure_ascii=False),encoding='utf-8'),
                cookies=COOKIES
                )
        res=json.loads(r1.text)
        if res['BaseResponse']['Ret']==0 and  len(res['BaseResponse']['ErrMsg'])==0:
            pass
        else:
            status=False
    res_dict={}
    if status:
        res_dict['code']=200
        res_dict['status']='消息发送成功！！'
    else:
        res_dict['code']=500
        res_dict['status']='出现未知错误，请联系管理员！！'

    return HttpResponse(json.dumps(res_dict,ensure_ascii=False))

def report(request):
    global MemberList
    if logoff is False:
        try:
            print('生成用户报表数据-------------')
            #统计性别
            boy=0
            girl=0
            null=0
            for item in MemberList:
                if item['Sex'] == 1:
                    boy+=1
                elif item['Sex'] == 2:
                    girl+=1
                else:
                    null+=1
            #统计所在地区（按城市排列）
            city=[]
            city_dict={}
            for item in MemberList:
                city.append(item['City'])
            city_set=list(set(city))
            city_set[0]=None
            city_set.remove(None)
            for city_name in city_set:
                city_dict[city_name]=0
            for i in MemberList:
                if i['City'] in city_dict:
                    city2=i['City']
                    city_dict[city2]=city_dict[city2]+1
            exist_sity_count=0
            for k,v in city_dict.items():
                exist_sity_count+=v
            null_city=len(MemberList)-exist_sity_count  #未设置城市的用户
            city_dict['未设置']=null_city

            return render(request,'report.html',{
                'boy':boy,
                'girl':girl,
                'null':null,
                'city_dict':city_dict,
                'MemberCount':len(MemberList),
                'userinfo':USER_INFO,
                'url_path':request.path,
                'head_jpg':head_jpg
            })
        except Exception as e:
            print('用户展示报表出现错误：',e)
            return redirect('/')
    else:
        return redirect('/')